package org.example.chapter8.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.example.chapter8.codec.PacketCodecHandler;
import org.example.chapter8.codec.Spliter;
import org.example.chapter8.handler.IMIdleStateHandler;
import org.example.chapter8.server.handler.*;

import java.util.Date;

public class NettyServer {

    private static final int PORT = 8000;

    public static void main(String[] args) throws Exception {
        // 创建两个线程组 boosGroup、workerGroup
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        // 创建服务端的启动对象，设置参数
        ServerBootstrap bootstrap = new ServerBootstrap();
        // 设置两个线程组boosGroup和workerGroup
        bootstrap.group(bossGroup, workerGroup)
                // 设置服务端通道实现类型
                .channel(NioServerSocketChannel.class)
                // 设置线程队列得到连接个数
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childOption(ChannelOption.TCP_NODELAY, true)
                // 设置保持活动连接状态
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) {
                        // 给pipeline管道设置处理器
                        // socketChannel.pipeline().addLast(new IMIdleStateHandler());
                        socketChannel.pipeline().addLast(new Spliter());
                        socketChannel.pipeline().addLast(PacketCodecHandler.INSTANCE);
                        socketChannel.pipeline().addLast(LoginRequestHandler.INSTANCE);
                        socketChannel.pipeline().addLast(HeartBeatRequestHandler.INSTANCE);
                        socketChannel.pipeline().addLast(AuthHandler.INSTANCE);
                        socketChannel.pipeline().addLast(IMHandler.INSTANCE);
                    }
                });
        // 绑定端口号，启动服务端
        bind(bootstrap);
    }

    private static void bind(final ServerBootstrap serverBootstrap) {
        serverBootstrap.bind(NettyServer.PORT).addListener(future -> {
            if (future.isSuccess()) {
                System.out.println(new Date() + ": 端口[" + NettyServer.PORT + "]绑定成功！");
            } else {
                System.err.println("端口[" + NettyServer.PORT + "]绑定失败！");
            }
        });
    }
}